﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using ColorRichTextBox.ColorRichTextBox;
using GAM_Web_Designer_Pro.Properties;

namespace GAM_Web_Designer_Pro.Forms {
    public partial class ProjectPanelUserControl : UserControl {

        private string currentDir;
        private string projectName = string.Empty;
        private MainForm _parent;

        public string CurrentDirectory {
            get {
                return currentDir;
            }
            set {
                currentDir = value;
            }
        }

        public MainForm CurrentParent {
            get {
                return _parent;
            }
            set {
                _parent = value;
            }
        }

        public ProjectPanelUserControl() {
            InitializeComponent();
            this._parent = (MainForm)this.ParentForm;
            currentDir = Environment.GetFolderPath( Environment.SpecialFolder.MyDocuments );            
            DrawDirectory();
        }

        public ProjectPanelUserControl( MainForm parent ) {
            InitializeComponent();
            this._parent = parent;
            currentDir = Environment.GetFolderPath( Environment.SpecialFolder.MyDocuments );
            DrawDirectory();
        }

        private void ProjectPanelUserControl_Load( object sender, EventArgs e ) {

        }

        private void addtoolStripButton_Click( object sender, EventArgs e ) {
            
            // Get currently selected node and remove the project name from path.
            string currentlySelectedNode = GetCurrentlySelectNodesPath();

            // Get the FileAttributes for the currently selected node.
            FileAttributes att = File.GetAttributes( currentDir + "\\" + currentlySelectedNode );

            // If the node is a file.
            if ( ( att & FileAttributes.Directory ) != FileAttributes.Directory )
                new NewFileForm( (MainForm)_parent, false, currentDir ).ShowDialog( this );

            // If the node is a directory you need to pass the selected node
            // as part of the directory string when creating a new file.
            else
                new NewFileForm( (MainForm)_parent, false, currentDir + "\\" + currentlySelectedNode ).ShowDialog( this );
            
            // Finally redraw the current directory.
            ReDrawDirectory( currentDir, projectName );
        }

        private void edittoolStripButton_Click( object sender, EventArgs e ) {
            _fileTV_DoubleClick( sender, e );
        }

        private void deletetoolStripButton_Click( object sender, EventArgs e ) {
            try {

                // Get currently selected node and remove the project name from path.
                string currentlySelectedNode = GetCurrentlySelectNodesFullPath();
                string path = currentDir + "\\" + currentlySelectedNode;
                FileAttributes attributes = File.GetAttributes( path );

                if ( ( attributes & FileAttributes.Directory ) != FileAttributes.Directory ) {
                    File.Delete( path );
                    MessageBox.Show( path + " Deleted", string.Empty, MessageBoxButtons.OK, MessageBoxIcon.Information );
                    ReDrawDirectory( currentDir, projectName );
                }
                else {
                    Directory.Delete( path, true );
                    MessageBox.Show( path + " Deleted", string.Empty, MessageBoxButtons.OK, MessageBoxIcon.Information );
                    ReDrawDirectory( currentDir, projectName );
                }

            }
            catch ( NullReferenceException ) {
                MessageBox.Show( "You must select a file or directory to delete.", "Error!", MessageBoxButtons.OK, MessageBoxIcon.Error );
            }
            catch ( Exception ex ) {
                new BugReporter.BugReporterForm( Application.ProductName,
                    Application.ProductVersion, ex.ToString(), ex.Message ).Show();
            }
        }

        /// <summary>
        /// Gets the currently selected node's full path 
        /// excluding the project name and if the node is
        /// a file removes the file name and extension 
        /// from the path.
        /// </summary>
        /// <returns>The currently selected node's path</returns>
        private String GetCurrentlySelectNodesPath() {

            try {

                // Get currently selected node and remove the project name from path.
                string currentlySelectedNode = _fileTV.SelectedNode.FullPath.Remove( 0, projectName.Length ).TrimStart( '\\' );

                // Get the FileAttributes for the currently selected node.
                FileAttributes att = File.GetAttributes( currentDir + "\\" + currentlySelectedNode );

                // If the node is a file.
                if ( ( att & FileAttributes.Directory ) != FileAttributes.Directory ) {
                    currentlySelectedNode = currentlySelectedNode.Remove( ( currentlySelectedNode.Length - _fileTV.SelectedNode.Text.Length ),
                        _fileTV.SelectedNode.Text.Length).TrimEnd('\\');
                    return currentlySelectedNode;
                }
                // If the node is a directory you need to pass the selected node
                // as part of the directory string when creating a new file.
                else
                    return currentlySelectedNode;

            }
            catch ( NullReferenceException ) {
                
            }
            return string.Empty;
        }

        /// <summary>
        /// Gets the currently selected node's full path 
        /// excluding the project name.
        /// </summary>
        /// <returns>The currently selected node full path.</returns>
        private String GetCurrentlySelectNodesFullPath() {

            // Get currently selected node and remove the project name from path.
            string currentlySelectedNode = _fileTV.SelectedNode.FullPath.Remove( 0, projectName.Length ).TrimStart( '\\' );
            return currentlySelectedNode;

        }

        private void ProcessDir( TreeNode node, DirectoryInfo dirInfo ) {

            try {

                TreeNode rootNode = node;
                FileInfo[] files = dirInfo.GetFiles();
                foreach ( FileInfo info in files ) {
                    string name = info.FullName.Replace( node.FullPath + "\\", string.Empty );
                    if ( name.EndsWith( Settings.Default.ProjectExt ) )
                        continue;
                    rootNode.Nodes.Add( name, name, 1 );
                    
                }

                DirectoryInfo dirinfo = new DirectoryInfo( node.FullPath );
                DirectoryInfo[] dirs = dirinfo.GetDirectories();
                foreach ( DirectoryInfo item in dirs ) {
                    rootNode = new TreeNode( item.FullName.Replace( node.FullPath + "\\", string.Empty ) );
                    rootNode.ImageIndex = 0;
                    node.Nodes.Add( rootNode );
                    ProcessDir( rootNode, item );
                }

            }
            catch ( NotSupportedException ) {
                
            }
            catch ( UnauthorizedAccessException ) {

            }
            catch ( DirectoryNotFoundException ) {

            }
            catch ( Exception ex ) {
                new BugReporter.BugReporterForm( Application.ProductName,
                      Application.ProductVersion, ex.ToString(), ex.Message ).Show();
            }

        }

        private void ProcessDir( TreeNode node, DirectoryInfo dirInfo, string dirPath ) {

            try {

                TreeNode rootNode = node;
                FileInfo[] files = dirInfo.GetFiles();
                foreach ( FileInfo info in files ) {
                    string name = info.FullName.Replace( dirPath + "\\", string.Empty );
                    if ( name.EndsWith( Settings.Default.ProjectExt ) )
                        continue;
                    rootNode.Nodes.Add( name, name, 1 );

                }

                DirectoryInfo dirinfo = new DirectoryInfo( dirPath );
                DirectoryInfo[] dirs = dirinfo.GetDirectories();
                foreach ( DirectoryInfo item in dirs ) {
                    rootNode = new TreeNode( item.FullName.Replace( dirPath + "\\", string.Empty ) );
                    rootNode.ImageIndex = 0;
                    node.Nodes.Add( rootNode );
                    ProcessDir( rootNode, item, dirPath + "\\" + rootNode.Text );
                }

            }
            catch ( NotSupportedException ) {

            }
            catch ( UnauthorizedAccessException ) {

            }
            catch ( DirectoryNotFoundException ) {

            }
            catch ( Exception ex ) {
                new BugReporter.BugReporterForm( Application.ProductName,
                      Application.ProductVersion, ex.ToString(), ex.Message ).Show();
            }

        }

        private void DrawDirectory() {
            DirectoryInfo info = new DirectoryInfo( currentDir );
            TreeNode node = new TreeNode( info.FullName );
            _fileTV.Nodes.Add( node );
            ProcessDir( node, info );
        }

        private void DrawDirectory( string name ) {
            DirectoryInfo info = new DirectoryInfo( currentDir );
            TreeNode node = new TreeNode( name );
            _fileTV.Nodes.Add( node );
            ProcessDir( node, info, info.FullName );
        }

        /// <summary>
        /// Redraws the current working directory.
        /// </summary>
        public void ReDrawDirectory() {
            _fileTV.Nodes.Clear();
            DrawDirectory();
        }

        /// <summary>
        /// Alllows you to redraw the file tree with a specfic directory.
        /// </summary>
        /// <param name="newDir">The directory to draw.</param>
        public void ReDrawDirectory( string newDir ) {
            currentDir = newDir;
            _fileTV.Nodes.Clear();
            DrawDirectory();
        }

        /// <summary>
        /// Alllows you to redraw the file tree with a specfic directory.
        /// </summary>
        /// <param name="newDir">The directory to draw.</param>
        /// <param name="projectName">The name of the open project</param>
        public void ReDrawDirectory( string newDir, string projectName ) {
            currentDir = newDir;
            this.projectName = projectName;
            _fileTV.Nodes.Clear();
            DrawDirectory( projectName );
        }

        private void _fileTV_DoubleClick( object sender, System.EventArgs e ) {
            try {

                SortedList<string, clsColorRichTextBoxSchema> schemas = MainForm.CurrentSchemas;
                string path;
                if ( projectName != string.Empty )
                    path = currentDir.Replace( projectName, string.Empty ) + _fileTV.SelectedNode.FullPath;
                else
                    path = _fileTV.SelectedNode.FullPath;
                clsColorRichTextBoxSchema currentSchema = null;
                FileAttributes attributes = File.GetAttributes( path );

                if ( ( attributes & FileAttributes.Directory ) != FileAttributes.Directory ) {

                    if ( path.EndsWith( ".wdp" ) ) {
                        MainForm form = (MainForm)ParentForm;
                        form.CurrentProject = ProjectAccess.LoadProject( path );
                        this.ReDrawDirectory( form.CurrentProject.Directory );
                        this.Visible = true;
                    }
                    else {
                        foreach ( clsColorRichTextBoxSchema schema in schemas.Values ) {
                            if ( currentSchema != null )
                                break;

                            foreach ( string str in schema.ExtensionsSupported ) {
                                if ( path.EndsWith( str ) ) {
                                    currentSchema = schema;
                                    break;
                                }
                            }
                        }

                        if ( currentSchema == null )
                            currentSchema = new clsColorRichTextBoxSchema( clsColorRichTextBoxSchema.enDefaultColorSchemaTypes.Other );

                        if ( currentSchema.SchemeType.Equals( "IMAGE" ) )
                            new ViewImageForm( path ).ShowDialog( _parent );
                        else {

                            MainForm p = (MainForm)_parent;
                            DocumentForm form;

                            if ( currentSchema.SchemeType.Equals( "HTML" ) )
                                form = new DocumentForm( path, currentSchema, p, true );
                            else
                                form = new DocumentForm( path, currentSchema, p, false );

                            form.MdiParent = _parent;
                            form.Text = GetCurrentlySelectNodesFullPath();
                            p.CurrentForms.Add( form );
                            p.ActiveChildForm = form;
                            form.Show();
                        }
                    }

                }

            }
            catch ( NullReferenceException ) {
            }
            catch ( NotSupportedException ) {
            }
            catch ( Exception ex ) {
                new BugReporter.BugReporterForm( Application.ProductName,
                    Application.ProductVersion, ex.ToString(), ex.Message ).Show();
            }
        }

        private void addToolStripMenuItem_Click( object sender, EventArgs e ) {
            addtoolStripButton_Click( sender, e );
        }

        private void addFolderToolStripMenuItem_Click( object sender, EventArgs e ) {
            NewFolderForm form = new NewFolderForm();
            if ( form.ShowDialog( _parent ) == DialogResult.OK ) {
                string path = currentDir + "\\" + GetCurrentlySelectNodesPath() + "\\" + form.DirectoryName;
                Directory.CreateDirectory( path );
                ReDrawDirectory( currentDir, projectName );
            }
        }

        private void editToolStripMenuItem_Click( object sender, EventArgs e ) {
            edittoolStripButton_Click( sender, e );
        }

        private void deleteToolStripMenuItem_Click( object sender, EventArgs e ) {
            deletetoolStripButton_Click( sender, e );
        }

        private void _fileTV_AfterSelect( object sender, TreeViewEventArgs e ) {
            
        }

    }
}
